package luz.javaproxy.plugins.GuiLogger;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;

import luz.javaproxy.plugin.PluginInterface;

import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;



public class GuiLoggerTable extends JTable{
	private static final long serialVersionUID = 534648762781480107L;
	private final MyTableModel model;
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd@HH:mm:ss,SSS");
	
	public GuiLoggerTable(int limit){
		super();

		model=new MyTableModel(limit);
		this.setModel(model);
		this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.setSelectionBackground(this.getBackground());
		this.setSelectionForeground(this.getForeground());
		
		JTextField cellTxt = new JTextField();
		cellTxt.setOpaque(false);
		cellTxt.setBorder(BorderFactory.createEmptyBorder(0,1,0,0)); 
		DefaultCellEditor cellEdit = new DefaultCellEditor(cellTxt);
		cellEdit.setClickCountToStart(1);
		this.getColumnModel().getColumn(0).setCellEditor(cellEdit);
		this.getColumnModel().getColumn(1).setCellEditor(cellEdit);
		this.getColumnModel().getColumn(2).setCellEditor(cellEdit);
		
		
		this.getColumnModel().getColumn(0).setMinWidth(140);
		this.getColumnModel().getColumn(0).setMaxWidth(140);
		this.getColumnModel().getColumn(2).setMinWidth(170);
		this.getColumnModel().getColumn(2).setMaxWidth(170);
	}

	public void addPackets(HttpRequest request, HttpResponse response) {
		model.addPackets(request, response);
	}
	
	public void setLimit(int limit){
		model.setLimit(limit);
	}	

	public void clear() {
		model.clear();		
	}
	
	
	private static class MyTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 7780019195084742274L;
		private String[] columnNames = {"Date", "Request", "Respose"};
	    private List<Object[]> packets = new LinkedList<Object[]>();
	    private int limit;
	    
	    public MyTableModel(int limit){
	    	this.limit=limit;
	    }
	    	
		public void clear() {
			packets.clear();
			fireTableDataChanged();
		}

		public void addPackets(HttpRequest request, HttpResponse response){
			packets.add(new Object[]{new Date(),request, response});
			if (packets.size()>limit){
				packets.remove(0);
				fireTableRowsDeleted(0, 0);
			}
			int last=getRowCount();
			fireTableRowsInserted(last, last);
		}
	    
		public void setLimit(int limit){
			this.limit=limit;
			
			int diff=getRowCount()-limit;
			if (diff>0){
				for (int i = 0; i < diff; i++)
					packets.remove(0);
				fireTableDataChanged();
			}
		}
	    
	    @Override
	    public int getColumnCount() {
	        return columnNames.length;
	    }
	    
	    @Override
	    public int getRowCount() {
	        return packets.size();
	    }
	    
	    @Override
	    public String getColumnName(int col) {
	        return columnNames[col];
	    }
	    
	    @Override
	    public Object getValueAt(int row, int col) {
	    	
	    	switch (col){
	    		case 0:
	    			Date d = (Date)packets.get(row)[0];
	    			return d==null?null:sdf.format(d);
	    		
	    		case 1: 
	    			HttpRequest r = (HttpRequest)packets.get(row)[1];
	    			if (r==null)
	    				return null;
	    			else if (r.getParams().getParameter(PluginInterface.PROXY)!=null){
	    				return r.getRequestLine();
	    			} else {
	    				StringBuilder sb = new StringBuilder();
	    				sb.append(r.getRequestLine().getMethod());
	    				sb.append(' ');
	    				sb.append("http://");
	    				sb.append(r.getFirstHeader("Host").getValue());
	    				sb.append(r.getRequestLine().getUri());
	    				sb.append(' ');
	    				sb.append(r.getProtocolVersion());
	    				return sb.toString();
	    			}
	    		case 2: 
	    			HttpResponse s = (HttpResponse)packets.get(row)[2];
	    			return s==null?null:s.getStatusLine();
	    		default: return null;
	    	}
	    }
	    
		@Override
	    @SuppressWarnings("unchecked")
	    public Class getColumnClass(int c) {
	    	Object r = getValueAt(0, c);
	        return r!=null?r.getClass():Object.class;
	    }
		
		@Override
		public boolean isCellEditable(int rowIndex, int columnIndex) {
			return true;
		}

	}


	
}
